using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Web.UI.WebControls;
using System.Reflection;
using System.ServiceModel;
using RealWorld.Grids;
using GSBClient;

/******
 *
    Copyright 2008 Mitch Barnett
	This file is part of Global System Builder.

    Global System Builder is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Global System Builder is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Global System Builder.  If not, see <http://www.gnu.org/licenses/>.
 *
******/


public partial class _Default : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler 
{
    //to keep track of which row index was clicked
    private static int myrowIndex;
    private static int myrowIndex1;

    //this is the var that the Callback returns
    protected String returnvalue;

    //global to hold assembly names
    public static ArrayList gblAssemblyNameArray;

    //global to hold type names
    public static ArrayList gblTypeNameArray;

    //TODO: maybe a temp right now
    public static int selectedTypeIndex;

    // WCF client var
    private GSBClient.GSBServiceClient client;

    protected void Page_Load(object sender, EventArgs e)
    {
        //TODO: error handling here
        this.client = Global.Client;

        //check to see that this is not a postback
        if (!IsPostBack)
        {
            //hhhmmmmm
  
        }
            //CallBack script
            String cbReference = Page.ClientScript.GetCallbackEventReference(this, "arg", "ReceiveServerData", "context");
            String callbackScript;
            callbackScript = "function CallServer(arg, context)" + "{ " + cbReference + ";}";
            Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", callbackScript, true);
    }

    
    public void RaiseCallbackEvent(String eventArgument)
    {
        //the event argument is the passed in value from the CallServer Javascript function
        string s = eventArgument;  
        returnvalue = s;
    }

    public string GetCallbackResult()
    {
        //ok rude hack here just to get a file into the editor with no error handling
        StreamReader sr = new StreamReader("C:\\projects\\gsbservice\\simple.py");

        string sLine = "";
        string sCode = "";

        //Continue to read until you reach end of file
        while (sLine != null)
        {

            sLine = sr.ReadLine();
            if (sLine != null)
                //arrText.Add((sLine) + Environment.NewLine);
                sCode = sCode + (sLine + Environment.NewLine);
        }

        //close the file
        sr.Close();

        returnvalue = sCode;
        
        return returnvalue;    
    }

    public void RegisterClientScriptBlock (Type type,string key,string script)
    {
    
    }

    private void ListAssemblies()
    {
        Array aArray;
        ArrayList assemblyNameArray = new ArrayList();

        aArray = this.client.ListAssemblies();
        foreach (string a in aArray)
        {
            ReflectionOutput myReflectionOutput1 = new ReflectionOutput();
            myReflectionOutput1.Image = ("~\\Images\\assembly.gif");
            myReflectionOutput1.StaticImage = ("~\\Images\\empty.gif");
            myReflectionOutput1.ReflectionDescription = a;
            assemblyNameArray.Add(myReflectionOutput1);
        }
        assemblyNameArray.Sort();
        gblAssemblyNameArray = assemblyNameArray;
        AssembliesGridView.DataSource = assemblyNameArray;
        AssembliesGridView.DataBind();   
    }


    private void ListTypes(string assemblyname)
    {
        PropsGridView.Controls.Clear();
        MethodsGridView.Controls.Clear();
        EventsGridView.Controls.Clear();

        ArrayList typeNameArray = new ArrayList();

        Dictionary<string,object[]> aDictionary = new Dictionary<string,object[]>();

        aDictionary = this.client.ListTypes(assemblyname);

        foreach (KeyValuePair<string, object[]> kvp in aDictionary)
        {
            string typekey = (string)kvp.Key;
            Array typesvalue = (Array)kvp.Value;

            if (typekey == "class")
            {
                foreach (string typename in typesvalue)
                {
                    ReflectionOutput myReflectionOutput1 = new ReflectionOutput();
                    myReflectionOutput1.Image = ("~\\Images\\pubclass.gif");
                    myReflectionOutput1.StaticImage = ("~\\Images\\empty.gif");
                    myReflectionOutput1.ReflectionDescription = typename;
                    typeNameArray.Add(myReflectionOutput1);
                }
            }

            if (typekey == "enum")
            {
                foreach (string typename in typesvalue)
                {
                    ReflectionOutput myReflectionOutput2 = new ReflectionOutput();
                    myReflectionOutput2.Image = ("~\\Images\\pubenum.gif");
                    myReflectionOutput2.StaticImage = ("~\\Images\\empty.gif");
                    myReflectionOutput2.ReflectionDescription = typename;
                    typeNameArray.Add(myReflectionOutput2);
                }
            }

            if (typekey == "interface")
            {
                foreach (string typename in typesvalue)
                {
                    ReflectionOutput myReflectionOutput3 = new ReflectionOutput();
                    myReflectionOutput3.Image = ("~\\Images\\pubinterface.gif");
                    myReflectionOutput3.StaticImage = ("~\\Images\\empty.gif");
                    myReflectionOutput3.ReflectionDescription = typename;
                    typeNameArray.Add(myReflectionOutput3);
                }
            }

        }

        typeNameArray.Sort();

        gblTypeNameArray = typeNameArray;
        TypesGridView.DataSource = typeNameArray;
        TypesGridView.DataBind();


    }

    private void ListMembers(string typename)
    {
        PropsGridView.Controls.Clear();
        MethodsGridView.Controls.Clear();
        EventsGridView.Controls.Clear();

        ArrayList propsNameArray = new ArrayList();
        ArrayList methodsNameArray = new ArrayList();
        ArrayList eventsNameArray = new ArrayList();

        Dictionary<string, object[]> aDictionary = new Dictionary<string, object[]>();

        try
        {
            //call to WCF service to return members
            aDictionary = this.client.ListMembers(typename);
        }
        catch (CommunicationException commessage)
        {
            throw new CommunicationException(commessage.Message + commessage.StackTrace);
        }


        foreach (KeyValuePair<string, object[]> kvp in aDictionary)
        {
            string memberkey = kvp.Key;
            Array membervalues = (Array)kvp.Value;

            if (memberkey == "staticfields")
            {
                foreach (string mv in membervalues)
                {
                    ReflectionOutput myReflectionOutput1 = new ReflectionOutput();
                    myReflectionOutput1.Image = ("~\\Images\\pubfield.gif");
                    myReflectionOutput1.StaticImage = ("~\\Images\\static.gif");
                    myReflectionOutput1.ReflectionDescription = mv;
                    propsNameArray.Add(myReflectionOutput1);
                }
            }

            if (memberkey == "staticproperties")
            {
                foreach (string mv in membervalues)
                {
                    ReflectionOutput myReflectionOutput1 = new ReflectionOutput();
                    myReflectionOutput1.Image = ("~\\Images\\pubproperty.gif");
                    myReflectionOutput1.StaticImage = ("~\\Images\\static.gif");
                    myReflectionOutput1.ReflectionDescription = mv;
                    propsNameArray.Add(myReflectionOutput1);
                }
            }

            if (memberkey == "staticevents")
            {
                foreach (string mv in membervalues)
                {
                    ReflectionOutput myReflectionOutput1 = new ReflectionOutput();
                    myReflectionOutput1.Image = ("~\\Images\\pubevent.gif");
                    myReflectionOutput1.StaticImage = ("~\\Images\\static.gif");
                    myReflectionOutput1.ReflectionDescription = mv;
                    eventsNameArray.Add(myReflectionOutput1);
                }
            }

            if (memberkey == "staticmethods")
            {
                foreach (string mv in membervalues)
                {
                    ReflectionOutput myReflectionOutput1 = new ReflectionOutput();
                    myReflectionOutput1.Image = ("~\\Images\\pubmethod.gif");
                    myReflectionOutput1.StaticImage = ("~\\Images\\static.gif");
                    myReflectionOutput1.ReflectionDescription = mv;
                    methodsNameArray.Add(myReflectionOutput1);
                }
            }

            if (memberkey == "constructors")
            {
                foreach (string mv in membervalues)
                {
                    ReflectionOutput myReflectionOutput1 = new ReflectionOutput();
                    myReflectionOutput1.Image = ("~\\Images\\pubmethod.gif");
                    myReflectionOutput1.StaticImage = ("~\\Images\\empty.gif");
                    myReflectionOutput1.ReflectionDescription = mv;
                    methodsNameArray.Add(myReflectionOutput1);
                }
            }

            if (memberkey == "instancefields")
            {
                foreach (string mv in membervalues)
                {
                    ReflectionOutput myReflectionOutput1 = new ReflectionOutput();
                    myReflectionOutput1.Image = ("~\\Images\\pubfield.gif");
                    myReflectionOutput1.StaticImage = ("~\\Images\\empty.gif");
                    myReflectionOutput1.ReflectionDescription = mv;
                    propsNameArray.Add(myReflectionOutput1);
                }
            }

            if (memberkey == "instanceproperties")
            {
                foreach (string mv in membervalues)
                {
                    ReflectionOutput myReflectionOutput1 = new ReflectionOutput();
                    myReflectionOutput1.Image = ("~\\Images\\pubproperty.gif");
                    myReflectionOutput1.StaticImage = ("~\\Images\\empty.gif");
                    myReflectionOutput1.ReflectionDescription = mv;
                    propsNameArray.Add(myReflectionOutput1);
                }
            }

            if (memberkey == "instanceevents")
            {
                foreach (string mv in membervalues)
                {
                    ReflectionOutput myReflectionOutput1 = new ReflectionOutput();
                    myReflectionOutput1.Image = ("~\\Images\\pubevent.gif");
                    myReflectionOutput1.StaticImage = ("~\\Images\\empty.gif");
                    myReflectionOutput1.ReflectionDescription = mv;
                    eventsNameArray.Add(myReflectionOutput1);
                }
            }

            if (memberkey == "instancemethods")
            {
                foreach (string mv in membervalues)
                {
                    ReflectionOutput myReflectionOutput1 = new ReflectionOutput();
                    myReflectionOutput1.Image = ("~\\Images\\pubmethod.gif");
                    myReflectionOutput1.StaticImage = ("~\\Images\\empty.gif");
                    myReflectionOutput1.ReflectionDescription = mv;
                    methodsNameArray.Add(myReflectionOutput1);
                }
            }

        }
        //bind arraylists to repective GridViews
        propsNameArray.Sort();
        PropsGridView.DataSource = propsNameArray;
        if (propsNameArray.Count != 0)
        {
            PropsGridView.DataBind();
        }

        methodsNameArray.Sort();
        MethodsGridView.DataSource = methodsNameArray;
        if (methodsNameArray.Count != 0)
        {
            MethodsGridView.DataBind();
        }

        eventsNameArray.Sort();
        EventsGridView.DataSource = eventsNameArray;
        if (eventsNameArray.Count != 0)
        {
            EventsGridView.DataBind();
        }
    }


    private string splitTypeName(string s)
    {
        char[] delimiterChars = { '.', ' ', '\t' };
        string text = s;
        string[] words = text.Split(delimiterChars);
        int myLength = words.Length;
        return words.GetValue(myLength - 1).ToString();
    }

    protected void AssembliesGridView_RowClicked(object sender, GridViewRowClickedEventArgs args)
    {
        if (myrowIndex != args.Row.RowIndex)
        {
            args.Row.BackColor = System.Drawing.Color.Blue;
            args.Row.ForeColor = System.Drawing.Color.White;

            FrozenGridView mygrid = (FrozenGridView)sender;
            mygrid.Rows[myrowIndex].BackColor = System.Drawing.Color.White;
            mygrid.Rows[myrowIndex].ForeColor = System.Drawing.Color.Black;
            myrowIndex = args.Row.RowIndex;
        }
        else
        {
            args.Row.BackColor = System.Drawing.Color.Blue;
            FrozenGridView mygrid = (FrozenGridView)sender;
            mygrid.Rows[myrowIndex].ForeColor = System.Drawing.Color.White;
        }
        HF1.Value = "True";

        ReflectionOutput assemblyInfo = (ReflectionOutput)gblAssemblyNameArray[args.Row.DataItemIndex];
        ListTypes((string)assemblyInfo.ReflectionDescription);
        UpdatePanel1.Update();
    }

    protected void TypesGridView_RowClicked(object sender, GridViewRowClickedEventArgs args)
    {
        //TODO: fix bug when the types grid is smaller than the last caller.
        if (myrowIndex1 != args.Row.RowIndex)
        {
            args.Row.BackColor = System.Drawing.Color.Blue;
            args.Row.ForeColor = System.Drawing.Color.White;

            FrozenGridView mygrid1 = (FrozenGridView)sender;
            mygrid1.Rows[myrowIndex1].BackColor = System.Drawing.Color.White;
            mygrid1.Rows[myrowIndex1].ForeColor = System.Drawing.Color.Black;
            myrowIndex1 = args.Row.RowIndex;
        }
        else
        {
            args.Row.BackColor = System.Drawing.Color.Blue;
            FrozenGridView mygrid1 = (FrozenGridView)sender;
            mygrid1.Rows[myrowIndex].ForeColor = System.Drawing.Color.White;
        }
        HF1.Value = "False";

        ReflectionOutput typeInfo = (ReflectionOutput)gblTypeNameArray[args.Row.DataItemIndex];
        ListMembers((string)typeInfo.ReflectionDescription);
        UpdatePanel1.Update();
    }

    protected void PropsGridView_RowClicked(object sender, GridViewRowClickedEventArgs args)
    {
        //int test = args.Row.DataItemIndex;
        
    }

    protected void MethodsGridView_RowClicked(object sender, GridViewRowClickedEventArgs args)
    {

    }

    protected void EventsGridView_RowClicked(object sender, GridViewRowClickedEventArgs args)
    {

    }

    protected void HiddenFieldToUpdateGridPanel_ValueChanged(object sender, EventArgs e)
    {
        //this hidden field triggers the web app to communicate with
        //the remote GSB Service.  The caller is the console with the keyword "connect"
        //This branch gets the assemblies from the WCF ListBox and updates the client to show
        //the list of Assemblies through a call to UpdatePanel1

        ListAssemblies();

        UpdatePanel1.Update();
    } 
}